package com.heima.wemedia.service.impl;

import com.heima.common.exception.CustomException;

import com.heima.feigns.AdminFeign;
import com.heima.feigns.UserFeign;
import com.heima.model.common.constants.user.UserRelationConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.statistic.pojos.WmNewsStatistics;
import com.heima.model.wemedia.dtos.WmFollowFanceDTO;
import com.heima.model.wemedia.vos.WmFansImageVo;
import com.heima.model.threadlocal.WmThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.model.wemedia.vos.WmFansListVO;
import com.heima.model.wemedia.vos.WmFollowFanceVO;
import com.heima.wemedia.mapper.FansMapper;
import com.heima.wemedia.service.WmFansService;
import com.heima.wemedia.service.WmUserService;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WmFansServiceImpl implements WmFansService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    FansMapper fansMapper;
    @Autowired
    UserFeign userFeign;
    @Autowired
    AdminFeign adminFeign;
    @Autowired
    WmUserService wmUserService;
    @Value("${file.oss.web-site}")
    String webSite;
    /**
     *      粉丝画像
     * @return
     */
    @Override
    public ResponseResult<List<WmFansImageVo>> getFansImageDate() {
        //1.  登录校验  获取自媒体用户的ID
        WmUser user = WmThreadLocalUtils.getUser();
        System.out.println(user);
        if (user == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer wmId = user.getId();
        //通过WmID  获得 作者ID
        WmUser wmUser = wmUserService.getById(wmId);
        Integer apAuthorId = wmUser.getApAuthorId();
        log.info("当前登录的自媒体de id{}",wmId);
        log.info("当前登录的自媒体用户的作者id{}",apAuthorId);


        //2. 通过自媒体用户ID 在Redis的fens中  获取  男 女 的人数  并封装
        // 获取粉丝列表
        log.info("开始从redis中获取粉丝");
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
        Set<String> fansList = zSetOperations.range((UserRelationConstants.FANS_LIST + apAuthorId), 0, -1);

//        ListOperations<String,String> fansOps = redisTemplate.opsForList();
//        Long size = fansOps.size(UserRelationConstants.FANS_LIST + "4");
//        List fansList = redisTemplate.executePipelined(new RedisCallback<List<ApUser>>() {
//            @Override
//            public List<ApUser> doInRedis(RedisConnection connection) throws DataAccessException {
//                connection.lRange((UserRelationConstants.FANS_LIST + "4").getBytes(), 0, -1);
//                return null;
//            }
//        }, RedisSerializer.string());
////        List fansList = redisTemplate.boundListOps(UserRelationConstants.FANS_LIST + "4").range( 0, -1);
        log.info("开始从redis中获取粉丝结束");
        if (fansList == null) {
            //Todo:  粉丝的数据为0
            return ResponseResult.errorResult(9999,"没有粉丝");
        }
        ArrayList<WmFansImageVo> resultList = new ArrayList<>();

        Integer apUserId = 0;
        Integer maleNum = 0;
        Integer femaleNum = 0;
        Integer age20 = 0;
        Integer age40 = 0;
        Integer age40p = 0;
        // 得到粉丝的apUser对象
        for (String s : fansList) {
            apUserId=Integer.valueOf(s);
            ResponseResult<ApUser> feignResult = userFeign.findUserById(apUserId);

            if (!feignResult.checkCode()) {
                throw new CustomException(AppHttpCodeEnum.REMOTE_SERVER_ERROR);
            }
            ApUser apUser = feignResult.getData();
            //  男 0 male false
            if (apUser!=null&&apUser.getSex() != null && apUser.getSex() == false) {
                maleNum++;
            }
            //  女 1  female true
            if (apUser!=null&&apUser.getSex() != null && apUser.getSex() == true) {
                femaleNum++;
            }
            //3.  通过自媒体用户ID 在Redis的fens中  获取用户的年龄段   10-20   聚合   统计  大于小于   并封装

            if (apUser != null&&apUser.getAge()!=null) {
                switch ((Integer.valueOf(apUser.getAge())-1)/10){
                    case 0:;
                    case 1:age20++;break;
                    case 2:
                    case 3:age40++;break;
                    default:age40p++;break;

                }
            }

        }

//        List<ApUser> fansApUserList = fansMapper.findFansApUser(list);
//        //  过滤  男生 0 和女生 1性别
//        List<ApUser> manApUsers = fansApUserList.stream().map(apUser -> {
//                    ApUser apUser0 = new ApUser();
//                    if (apUser.getSex() != null && apUser.getSex() == false) {
//                        apUser0 = apUser;
//                    }
//                    return apUser0;
//                }
//        ).collect(Collectors.toList());
//        List<ApUser> womanApUsers = fansApUserList.stream().map(apUser -> {
//                    ApUser apUser1 = new ApUser();
//                    if (apUser.getSex() != null && apUser.getSex() == true) {
//                        apUser1 = apUser;
//                    }
//                    return apUser1;
//                }
//        ).collect(Collectors.toList());
        //////格式化时间
        SimpleDateFormat sdf1 =new SimpleDateFormat("yyyy-MM-dd" );
        Date nowDate= new Date();
        String str1 = sdf1.format(nowDate);
        //////封装性别视图
        WmFansImageVo wmFansImageVoMan = new WmFansImageVo();
        wmFansImageVoMan.setId(1);
        wmFansImageVoMan.setUser_id(wmId);
        wmFansImageVoMan.setName("sex:male");
        wmFansImageVoMan.setValue(maleNum);

        wmFansImageVoMan.setCreated_time(str1);
        WmFansImageVo wmFansImageVoWoman = new WmFansImageVo();
        wmFansImageVoWoman.setId(1);
        wmFansImageVoWoman.setUser_id(wmId);
        wmFansImageVoWoman.setName("sex:female");
//        fansVoWoman.setValue(womanApUsers.size());
        wmFansImageVoWoman.setValue(femaleNum);
        wmFansImageVoWoman.setCreated_time(str1);

        //////封装年龄VOS
        WmFansImageVo wmFansImageVoAge19 = new WmFansImageVo();
        wmFansImageVoAge19.setId(1);
        wmFansImageVoAge19.setUser_id(wmId);
        wmFansImageVoAge19.setName("age:0-20");
        wmFansImageVoAge19.setValue(age20);
        wmFansImageVoAge19.setCreated_time(str1);
        WmFansImageVo wmFansImageVoAge39 = new WmFansImageVo();
        wmFansImageVoAge39.setId(1);
        wmFansImageVoAge39.setUser_id(wmId);
        wmFansImageVoAge39.setName("age:20-30");
        wmFansImageVoAge39.setValue(age40);
        wmFansImageVoAge39.setCreated_time(str1);
        WmFansImageVo wmFansImageVoAge40p = new WmFansImageVo();
        wmFansImageVoAge39.setId(1);
        wmFansImageVoAge39.setUser_id(wmId);
        wmFansImageVoAge39.setName("age:40+");
        wmFansImageVoAge39.setValue(age40p);
        wmFansImageVoAge39.setCreated_time(str1);
        //////4.  todo:通过自媒体用户ID  获取近7天    粉丝的阅读量
        for (int i = 0; i < 7; i++) {
            Calendar c = Calendar.getInstance();
            int days = c.get(Calendar.DAY_OF_MONTH);
            c.set(Calendar.DAY_OF_MONTH,days-i);
            Date time = c.getTime();
            String newTime = sdf1.format(time);
//            System.out.println("Date结束日期+1 " +sdf1.format(time));

            String data = str1;
            log.info("date  str1{}",data);
            Query query = Query.query(Criteria.where("userId").is(wmId).and("creatTime").is(newTime));
            WmNewsStatistics one = mongoTemplate.findOne(query, WmNewsStatistics.class);
            if (one != null) {
                //  封装
                WmFansImageVo vo =new WmFansImageVo();
                vo.setId(1);
                vo.setUser_id(wmId);
                vo.setName("read:"+newTime);
                vo.setValue(one.getFanReadNum().intValue());
                vo.setCreated_time(str1);
                resultList.add(vo);
            }




        }


        //////数据加入集合

        resultList.add(wmFansImageVoMan);
        resultList.add(wmFansImageVoWoman);
        resultList.add(wmFansImageVoAge19);
        resultList.add(wmFansImageVoAge39);
        resultList.add(wmFansImageVoAge40p);

        return ResponseResult.okResult(resultList);

    }

    /**
     *      封装  视图  数据
     * @param wmId
     * @param s
     * @param maleNum
     * @return
     */
    private WmFansImageVo getFansImageVo(Integer wmId, String s, Integer maleNum,String creatTime ,List resultList) {
        WmFansImageVo wmFansImageVo = new WmFansImageVo();
        wmFansImageVo.setId(1);
        wmFansImageVo.setUser_id(wmId);
        wmFansImageVo.setName(s);
        wmFansImageVo.setValue(maleNum);
        wmFansImageVo.setCreated_time(creatTime);
        resultList.add(wmFansImageVo);
        return wmFansImageVo;
    }

    /**
     *  获取粉丝列表
     * @return
     */
    @Override
    public ResponseResult<List<WmFansListVO>> getList() {
        //获取当前 自媒体用户  wmUser
        WmUser user = WmThreadLocalUtils.getUser();
        Integer wmId = user.getId();
        //通过WmID  获得 作者ID
        WmUser wmUser = wmUserService.getById(wmId);
        Integer apAuthorId = wmUser.getApAuthorId();
        log.info("当前登录的自媒体用户的作者id{}",apAuthorId);

        //定义全局变量
        Integer apUserId;//app用户的id
        List<WmFansListVO> resultList= new ArrayList<>();

        log.info("开始从redis中获取粉丝");
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
        Set<String> fansList = zSetOperations.range((UserRelationConstants.FANS_LIST + apAuthorId), 0, -1);
        log.info("开始从redis中获取粉丝结束");
        for (String s : fansList) {
            apUserId=Integer.valueOf(s);
            ResponseResult<ApUser> feignResult = userFeign.findUserById(apUserId);
            if (!feignResult.checkCode()) {
                throw new CustomException(AppHttpCodeEnum.REMOTE_SERVER_ERROR);
            }
            //获得粉丝app用户信息
            ApUser apUser = feignResult.getData();
            String defaultImage ="material/2021/11/20211124/5263e2b53a3b471e92fb4751f175d245.jpg";
            if (apUser != null) {
                WmFansListVO wmFansListVO = new WmFansListVO();
//            String newId = String.valueOf(System.currentTimeMillis())+String.valueOf(apUser.getId());
                wmFansListVO.setId(1);
                wmFansListVO.setFans_name(apUser.getName());
                wmFansListVO.setFans_id(apUser.getId());
                wmFansListVO.setPhoto(apUser.getImage()==null?webSite+defaultImage: webSite+apUser.getImage());
                //是否否关注了粉丝   自媒体用户关注（follow）的列表中找 有没有粉丝
                Double score = zSetOperations.score(UserRelationConstants.FOLLOW_LIST + apAuthorId, String.valueOf(apUser.getId()));//
                if(score != null){
                    wmFansListVO.setIs_follow(true);
                }else {
                    wmFansListVO.setIs_follow(false);
                }
                resultList.add(wmFansListVO);
                List<WmFansListVO> resultList2 = resultList.stream().sorted(Comparator.comparing(WmFansListVO::getIs_follow).reversed()).collect(Collectors.toList());
                resultList=resultList2;
            }
        }
        return ResponseResult.okResult(resultList);
    }

    /**
     *      关注粉丝操作数据库的操作
     * @param dto
     * @return
     */
    @Override
    public ResponseResult change_follow_state(WmFollowFanceDTO dto) {
        // 1. 参数校验
        //    是否登录
        //获取当前 自媒体用户  wmUser
        WmUser user = WmThreadLocalUtils.getUser();
        if (user==null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer wmId = user.getId();
        //通过WmID  获得 作者ID
        WmUser wmUser = wmUserService.getById(wmId);

        Integer apAuthorId = wmUser.getApAuthorId();
        log.info("当前登录的自媒体用户的作者id{}",apAuthorId);


        //    state的值
        Boolean state = dto.getSwitchState();
        //   是否已经关注过 ZSCORE
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();

        //   自己不能关注自己
        if(apAuthorId == dto.getFansId()){
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_ALLOW,"自己不能关注和取关自己");
        }
        // 2. 判断state的值是否等于 true  是取关
        if(state){
            // 参数1: 在集合中找 (key)   参数2: 要找的元素    返回值: 如果有这个元素返回 score  如果没有返回null
            Double score = zSetOperations.score(UserRelationConstants.FOLLOW_LIST + dto.getFansId(), String.valueOf(apAuthorId));//
            if(score != null){
                throw new CustomException(AppHttpCodeEnum.DATA_EXIST,"你已经关注过该粉丝");
            }
            // 2.1 如果是true  关注该粉丝  ZADD  集合添加数据
            zSetOperations.add(UserRelationConstants.FOLLOW_LIST + apAuthorId,String.valueOf(dto.getFansId()),System.currentTimeMillis());
            zSetOperations.add(UserRelationConstants.FANS_LIST   + dto.getFansId(),String.valueOf(apAuthorId),System.currentTimeMillis());
        }else {
            // 2.2 如果是false  取关该粉丝  ZREM  集合删除数据
            zSetOperations.remove(UserRelationConstants.FOLLOW_LIST + apAuthorId,String.valueOf(dto.getFansId()));
            zSetOperations.remove(UserRelationConstants.FANS_LIST   + dto.getFansId(),String.valueOf(apAuthorId));
        }
        WmFollowFanceVO wmFollowFanceVO = new WmFollowFanceVO();
        wmFollowFanceVO.setSwitch_state(dto.getSwitchState());
        return ResponseResult.okResult(dto.getSwitchState());
    }


}
